/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.common.dataset.support.poi;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.vacoor.nothing.common.util.StringUtils;
import org.vacoor.nothing.common.util.Throwables;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author vacoor
 */
public class PoiWriter {
    private static final String DATE_FORMAT = "yyyy-MM-dd";
    private static final String DEFAULT_SHEET_NAME = "Sheet1";

    public <E> void exportExcel2003(String sheetName, List<E> data, OutputStream out) throws IOException {
        HSSFWorkbook workbook = new HSSFWorkbook();

        exportExcelUsePoi(workbook, sheetName, data, out);
    }

    public <E> void exportExcel2007(String sheetName, List<E> data, OutputStream out) throws IOException {
        SXSSFWorkbook workbook = new SXSSFWorkbook();

        exportExcelUsePoi(workbook, sheetName, data, out);
    }

    public <E> void exportExcelUsePoi(Workbook workbook, String sheetName, List<E> data, OutputStream out) {
        try {
            sheetName = StringUtils.hasText(sheetName) ? sheetName : DEFAULT_SHEET_NAME;
            Sheet sheet = workbook.createSheet(sheetName);
            String[] captions = buildExcelCaptions(data);

            // poi 不像 jxl 会自动设置style, poi 日期必须自行设置style
            CellStyle dateStyle = workbook.createCellStyle();
            dateStyle.setDataFormat(workbook.createDataFormat().getFormat(DATE_FORMAT));

            boolean hasCaptions = captions != null && captions.length > 0;
            // 写入标题
            if (hasCaptions) {
                Row row = sheet.createRow(0);
                for (int i = 0; i < captions.length; i++) {
                    row.createCell(i).setCellValue(captions[i]);
                }
                sheet.createFreezePane(0, 1, 0, 1); // 冻结首行
            }
        /*
        sheet.setDefaultColumnStyle(4, dateStyle);
        */

            // 写入行
            for (int r = 0; r < data.size(); r++) {
                E e = data.get(r);
                Object[] values = buildExcelData(e);
                Row row = sheet.createRow(hasCaptions ? r + 1 : r);

                if (values == null) {
                    continue;
                }

                // 写入列
                for (int c = 0; c < values.length; c++) {
                    Object value = values[c];
                    if (value == null) {
                        continue;
                    }

                    Cell cell = row.createCell(c);

                    if (value instanceof Boolean) {
                        cell.setCellValue((Boolean) value);
                    } else if (value instanceof Number) {
                        cell.setCellValue(((Number) value).doubleValue());
                    } else if (value instanceof Date) {
                        cell.setCellValue((Date) value);
                        cell.setCellStyle(dateStyle);
                    } else if (value instanceof Calendar) {
                        cell.setCellValue((Calendar) value);
                        cell.setCellStyle(dateStyle);
                    } else {
                        // cell.setCellType(Cell.CELL_TYPE_STRING);
                        cell.setCellValue(value.toString());
                    }
                }
            }

            workbook.write(out);
            System.gc();
        } catch (Exception e) {
            throw Throwables.unchecked(e);
        }
    }

    private <E> Object[] buildExcelData(E e) {
        return new Object[0];
    }

    private <E> String[] buildExcelCaptions(List<E> data) {
        return new String[0];
    }
}
